www.gusucode.com > VC++ RingSDK界面库 > VC++ RingSDK界面库/code/libsrc/ringlib/thread.cpp

    /**********************************************************************
//
//
//        ##########                          ######  #########   # ######    #
//      #############                      ########### ######### #########  ###
//     ######## # ###  ##                 ############# ##    ## #####  # ####
//     ####  ##    ## ###                 ###     ### # #      #####   #####
//          #     ###  #            #     ##       ##  ##      ##     ###
//         ## ###### ##      ##  ####    ####          #       #     ##
//       #########  ###  ## ### #######   ######      ##      ##    ###
//      ######      ##  ######  ##  ##       ####     #      ##     ####
//     #######     ##   ###### ##  ###          ##   ##     ###    ######
//     #########   ##  ###### ## ######         ### ##    ###      #  #####
//    ##    ###### ####### ### #### ##  ## #######  ########      ##    ####
//    ##      #### ###  #  ### ### ##  ##########   ######       ##      ####
//   ##         ##                ##   #########    ####         #         ##
//               #              ###
//                              ##
//                             ###
//                             ##
//
//
//							RingSDK类库 ringlib.lib
//作者:临风
//
//版本:1.0
//
//声明:本类库可以自由使用而不须对作者作出任何回报,但作者希望能得到
//		  你的鼓励和支持。你可以对类库源码作出修改和改进,但希望你能在
//		  修改的同时给作者一份同样的副本。
//		  本类库不得用于任何商业用途,如确实需要,请与作者联系。
//
//e-mail:ringphone@sina.com
//
//原文件名:thread.cpp
//
//说明:线程类实现代码
//
**********************************************************************/
#define MAKE_SELF_LIB

#include "ringlib.h"

RingThread::RingThread()
{
	m_handle = NULL;
	m_info = NULL;
	m_bQuit = FALSE;
	m_event = NULL;
	m_dwId = 0;
	m_dwExitCode = 0xFFFFFFFF;
}

RingThread::~RingThread()
{
	//等待30秒给线程自动退出,否则强行退出。	
	Quit();
	if(m_event)
		CloseHandle(m_event);
}
	
BOOL RingThread::Start(THREADPROC proc,LONG param)
{
	if(m_handle)
		return TRUE;	//已有线程运行
	if(proc)
		m_handle = NewThread((THREADPROC)proc,(LPVOID)param);
	return (BOOL)m_handle;
}

BOOL RingThread::CanContinue(DWORD dwMilSec/* = INFINITE*/)
{
	if(m_event == NULL)
		m_event = CreateEvent(NULL,TRUE,TRUE,NULL);

	return (WAIT_OBJECT_0 == WaitForSingleObject(m_event,dwMilSec));
}

void RingThread::Continue()
{
	m_crl.Enter();
	
	m_nEvCnt ++;
	
	if(m_event)
		SetEvent(m_event);
	else
		m_event = CreateEvent(NULL,TRUE,TRUE,NULL);

	m_crl.Leave();
}

void RingThread::Wait(BOOL bForceWait/*=FALSE*/)
{
	m_crl.Enter();

	if(bForceWait)
		m_nEvCnt = 0;
	else
		m_nEvCnt --;
	
	if(m_nEvCnt <= 0)
	{
		m_nEvCnt = 0;
		
		if(m_event)
			ResetEvent(m_event);
		else
			m_event = CreateEvent(NULL,TRUE,FALSE,NULL);
	}

	m_crl.Leave();
}

void RingThread::Pause()
{
	if(m_handle)
		SuspendThread(m_handle);
}

void RingThread::Resume()
{
	if(m_handle)
		ResumeThread(m_handle);
}

BOOL RingThread::SetPriority(int nPriority)
{
	if(m_handle)
		return SetThreadPriority(m_handle,nPriority);
	else
		return FALSE;
}

BOOL RingThread::PostMessage(UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	return PostThreadMessage(m_dwId,uMsg,wParam,lParam);
}

void RingThread::Quit(int nWaitSecond/*=30*/)
{
	if(m_handle == NULL)
		return;

	m_nWaitSecond = nWaitSecond;
	WaitQuit();
}

void RingThread::ThreadQuit(int nWaitSecond/*=30*/)
{
	if(m_bQuit || m_handle == NULL)	//m_bQuit = TRUE表示该退出线程已启动
		return;

	//启动退出线程,如果不创建退出线程,一旦退出代码在需要退出的线程中调用,会导致
	//暂时死锁,延续至等待线程退出的时间。
	m_nWaitSecond = nWaitSecond;
	HANDLE handle = NewThread((THREADPROC)QuitProc,this);
	CloseHandle(handle);
}

DWORD RingThread::NotifyThreadQuit()
{
	m_crl.Enter();
	try
	{
		if(m_handle)
			CloseHandle(m_handle);

		//重置参数,以备下一次启动	
		m_handle = NULL;
		delete m_info;
		m_info = NULL;
		m_bQuit = FALSE;
		m_nEvCnt = 0;
		
		if(m_event)
			SetEvent(m_event);
	}
	catch(...)
	{
	}
	m_crl.Leave();
	return m_dwExitCode;
}

DWORD WINAPI RingThread::ThreadProc(RingThInfo* obj)
{	
	if(obj)
	{
		try
		{
			obj->m_thread->m_dwId = GetCurrentThreadId();
			obj->m_thread->m_dwExitCode = 0xFFFFFFFF;
			try
			{
				obj->m_thread->m_dwExitCode = (obj->m_obj->*(obj->m_lpthreadFunc))(obj->m_param);
			}
			catch(...)
			{
			}
			return obj->m_thread->NotifyThreadQuit();			
		}
		catch(...)
		{
		}
	}
	return 0;
}

DWORD WINAPI RingThread::QuitProc(RingThread* obj)
{
	if(obj)
		return obj->WaitQuit();
	return 0;
}

DWORD RingThread::GetExitCode()
{
	if(m_handle == NULL)
		return m_dwExitCode;
	else
	{
		DWORD Code;
		if(GetExitCodeThread(m_handle,&Code))
			return Code;
		else
			return 0xFFFFFFFF;
	}	
}

DWORD RingThread::WaitQuit()
{
	try
	{
		DWORD code = STILL_ACTIVE;
		int cnt = 0;
		int max = m_nWaitSecond * 1000;	//毫秒
		//BOOL bAlive;

		do
		{
			if(code != STILL_ACTIVE)
				break;

			m_bQuit = TRUE;
			
			if(m_event)
				SetEvent(m_event);

			Sleep(1);
			cnt ++;
			if(cnt > max)
			{
				TerminateThread(m_handle,0xFFFFFFFF);
				break;
			}
			//m_crl.Enter();
			//bAlive = (m_handle && GetExitCodeThread(m_handle,&code));
			//m_crl.Leave();
		}while(m_handle && GetExitCodeThread(m_handle,&code));
		
		return NotifyThreadQuit();		
	}
	catch(...)
	{
	}
	return 0;
}